// NARCReader.cs:
// Reader for NARC files.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License.
// See LICENSE for more information.

using System;
using System.IO;

namespace SharpNitroLib.NARC
{
	/// <summary>
	/// Reader for NARC files.
	/// </summary>
    public class NARCReader
    {
    	/// <summary>
    	/// Binary reader for stream.
    	/// </summary>
        private BinaryReader _reader;

        /// <summary>
        /// Create an instance of NARCReader.
        /// </summary>
        /// <param name="stream">Source stream.</param>
        public NARCReader(Stream stream) : this(new BinaryReader(stream)) { }

        /// <summary>
        /// Create an instance of NARCReader.
        /// </summary>
        /// <param name="reader">Binary reader on source.</param>
        public NARCReader(BinaryReader reader)
        {
            _reader = reader;
        }

        /// <summary>
        /// Read NARC.
        /// </summary>
        /// <returns>NARC read.</returns>
        /// TODO: improved error handling.
        public NARC Read()
        {
            // NARC's are Nitro Files, so...
            var nitroFile = new NitroFileReader(_reader).Read();

            // Frames of NARC.
            var firstFrame = nitroFile.Frames[0];
            var fntbFrame  = nitroFile.Frames[1];
            var fimgFrame  = nitroFile.Frames[2];

            var fileCount = BitConverter.ToUInt32(firstFrame.FrameData, 0);
            var fileEntries = new FATBEntry[fileCount];
            
            // Read FATB entries.
            for (var i = 0; i < fileCount; i++)
            {
                var entryOffset = 4 + i * 8;
                var fileEntry = new FATBEntry();
                fileEntry.Start = BitConverter.ToUInt32(firstFrame.FrameData, entryOffset);
                fileEntry.End = BitConverter.ToUInt32(firstFrame.FrameData, entryOffset + 4);
                fileEntries[i] = fileEntry;
            }
            
			// Create actual NARC.
            var narc = new NARC();
            
            // Add read entries to NARC.
            for (var i = 0; i < fileCount;++i )
            {
                var currentData = new byte[fileEntries[i].Size];
                // Copy bytes.
                // TODO: improve?
                for(var j=0; j<fileEntries[i].Size;++j)
                {
                    currentData[j] = fimgFrame.FrameData[fileEntries[i].Start + j];
                }
                narc.AddFileEntry(new NARCFileEntry()
                                      {
                                          Data = currentData, 
                                          Filename = String.Empty
                                      });
            }

            return narc;
        }
    }
}